Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Test the jumpstarter-driver-ssh identity key injection#689

Merged
kirkbrauer merged 2 commits intojumpstarter-dev:mainfrom
mangelajo:test-ssh-identity
Oct 4, 2025
Merged

Test the jumpstarter-driver-ssh identity key injection#689
kirkbrauer merged 2 commits intojumpstarter-dev:mainfrom
mangelajo:test-ssh-identity

Conversation

@mangelajo
Copy link
Copy Markdown
Member

@mangelajo mangelajo commented Oct 3, 2025

Follow up to #687

Summary by CodeRabbit

  • Tests
    • Expanded coverage for SSH identity handling, including identity strings and files, temporary key creation/cleanup, permission setting, error paths, and logging.
    • Validates command construction (-i usage, -l username, host, port, and mixed options) and return codes across scenarios, including when no identity is provided.
    • Improves reliability without altering public behavior; no user-facing changes or API updates.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 3, 2025

Walkthrough

Adds comprehensive tests in driver_test.py for SSH identity handling, covering identity strings, identity files, error cases, command construction, temporary key file creation/cleanup, and logging behaviors using a shared TEST_SSH_KEY constant.

Changes

Cohort / File(s) Summary
Tests: SSH identity handling
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py
Added tests for ssh_identity and ssh_identity_file configurations, validation errors, SSH command composition (-i, -l, host, port), temporary identity file lifecycle (creation, permissions, cleanup), error handling (OSError), and logging warnings. Introduces TEST_SSH_KEY constant.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor T as Test
  participant W as SSHWrapper
  participant TF as TempFile
  participant S as SSH Client/Process
  participant L as Logger

  T->>W: execute(cmd, host, user, options)
  alt identity string provided
    W->>TF: create temp key file (0600)
    TF-->>W: temp path or OSError
    alt TF error
      W->>L: warn/error (creation failed)
      W-->>T: raise error
    else success
      W->>S: ssh -i <temp> -l user host cmd
      S-->>W: return code/output
      W->>TF: cleanup
      alt cleanup fails
        W->>L: warn (cleanup failed)
      end
      W-->>T: result
    end
  else identity file provided
    W->>S: ssh -i <file> -l user host cmd
    S-->>W: result
    W-->>T: result
  else no identity
    W->>S: ssh -l user host cmd
    S-->>W: result
    W-->>T: result
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • jumpstarter-dev/jumpstarter#687 — Implements SSH identity handling and temp key file workflow that these tests exercise (creation, -i passing, and cleanup).

Poem

A whisk of keys, a hop of code,
I test the paths where secrets rode.
-i in paw, I tap and try,
Temp files bloom, then wave goodbye.
If cleanup squeaks, I log the tale—
A bunny’s craft, you shall not fail. 🐇🔑

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly summarizes the primary change, which is the addition of tests for SSH identity key injection in the jumpstarter-driver-ssh package. It is specific and concise, enabling teammates to quickly understand the focus of the pull request.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@netlify
Copy link
Copy Markdown

netlify bot commented Oct 3, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit 4ab21ac
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/68e1a7464daab200087ec094
😎 Deploy Preview https://deploy-preview-689--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py (2)

450-451: Ensure cross-platform temp path assertions.

The assertions for temp file paths assume Unix-like systems (/tmp or /var/tmp). On Windows, temp paths are typically in C:\Users\...\AppData\Local\Temp.

Apply this diff to make the assertion platform-independent:

+            import tempfile
             # The identity file should be a temporary file
             assert identity_file_path.endswith("_ssh_key")
-            assert "/tmp" in identity_file_path or "/var/tmp" in identity_file_path
+            assert tempfile.gettempdir() in identity_file_path

498-500: Ensure cross-platform temp path assertions.

Same issue as in test_ssh_command_with_identity_string: assertions assume Unix-like paths.

Apply this diff:

+                import tempfile as tmp_module
                 # The identity file should be a temporary file (not the original file)
                 assert identity_file_path.endswith("_ssh_key")
-                assert "/tmp" in identity_file_path or "/var/tmp" in identity_file_path
+                assert tmp_module.gettempdir() in identity_file_path
                 assert identity_file_path != temp_file_path
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6261b7c and 6fccabc.

📒 Files selected for processing (1)
  • packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py (3)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py (2)
  • SSHWrapper (9-51)
  • client (35-36)
packages/jumpstarter-driver-network/jumpstarter_driver_network/driver.py (1)
  • TcpNetwork (88-121)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/client.py (1)
  • run (45-75)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: check-warnings
  • GitHub Check: build
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
🔇 Additional comments (7)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py (7)

13-18: LGTM: Shared test constant improves maintainability.

The TEST_SSH_KEY constant centralizes the test SSH key content, making it easy to update if needed and ensuring consistency across all tests that use it.


360-374: LGTM: Validates identity string configuration.

The test correctly verifies that ssh_identity is set when provided as a string and that ssh_identity_file remains None.


404-412: LGTM: Validates mutual exclusivity of identity options.

The test correctly verifies that providing both ssh_identity and ssh_identity_file raises a ConfigurationError.


415-422: LGTM: Validates read error handling.

The test correctly verifies that attempting to read a nonexistent identity file raises a ConfigurationError with an appropriate error message.


516-546: LGTM: Validates absence of identity flag.

The test correctly verifies that when no identity is provided, the -i flag is not included in the SSH command.


587-609: LGTM: Validates temp file creation error handling.

The test correctly verifies that an OSError during temporary file creation is properly propagated within an ExceptionGroup wrapper.


611-649: LGTM: Validates graceful cleanup failure handling.

The test correctly verifies that when temporary file cleanup fails, a warning is logged and the SSH command execution still succeeds.

import tempfile

# Create a temporary file with SSH key content
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='_test_key') as temp_file:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Consider using binary mode for cross-platform consistency.

The PR description mentions opening files in "wb" mode to avoid CRLF format issues on Windows. This test uses text mode ('w'), which may introduce line ending conversions on Windows.

Apply this diff to align with the PR objectives:

-    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='_test_key') as temp_file:
+    with tempfile.NamedTemporaryFile(mode='wb', delete=False, suffix='_test_key') as temp_file:

And update the write call:

-        temp_file.write(TEST_SSH_KEY)
+        temp_file.write(TEST_SSH_KEY.encode('utf-8'))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='_test_key') as temp_file:
# write the SSH key in binary mode to avoid unwanted CRLF conversions on Windows
- with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='_test_key') as temp_file:
with tempfile.NamedTemporaryFile(mode='wb', delete=False, suffix='_test_key') as temp_file:
temp_file.write(TEST_SSH_KEY.encode('utf-8'))
🤖 Prompt for AI Agents
In packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py around
line 382, the temp file is opened in text mode ('w') which can cause CRLF
conversions on Windows; change the NamedTemporaryFile mode to 'wb' and update
the subsequent write call to write bytes (e.g., b'...') so the file is written
in binary with consistent line endings across platforms.

import tempfile

# Create a temporary file with SSH key content
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='_test_key') as temp_file:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Consider using binary mode for cross-platform consistency.

Same issue as in test_ssh_identity_file_configuration: using text mode ('w') may introduce line ending conversions on Windows.

Apply this diff:

-    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='_test_key') as temp_file:
+    with tempfile.NamedTemporaryFile(mode='wb', delete=False, suffix='_test_key') as temp_file:

And update the write call:

-        temp_file.write(TEST_SSH_KEY)
+        temp_file.write(TEST_SSH_KEY.encode('utf-8'))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='_test_key') as temp_file:
with tempfile.NamedTemporaryFile(mode='wb', delete=False, suffix='_test_key') as temp_file:
temp_file.write(TEST_SSH_KEY.encode('utf-8'))
🤖 Prompt for AI Agents
In packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py around
line 470, the temp file is opened in text mode ('w') which can cause CRLF
conversions on Windows; change the NamedTemporaryFile mode to binary ('wb') and
update the subsequent write call to write bytes (encode the string or use a
bytes literal) so the key is written verbatim across platforms.

result = client.run(False, ["hostname"])

# Verify temporary file was created
mock_temp_file.assert_called_once_with(mode='w', delete=False, suffix='_ssh_key')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update assertion to expect binary mode.

The test assertion expects mode='w', but per the PR objectives, the implementation should use mode='wb' to avoid CRLF issues on Windows.

Apply this diff:

-                        mock_temp_file.assert_called_once_with(mode='w', delete=False, suffix='_ssh_key')
+                        mock_temp_file.assert_called_once_with(mode='wb', delete=False, suffix='_ssh_key')

Additionally, update the mock to encode the SSH key:

-                        mock_temp_file_instance.write.assert_called_once_with(TEST_SSH_KEY)
+                        mock_temp_file_instance.write.assert_called_once_with(TEST_SSH_KEY.encode('utf-8'))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mock_temp_file.assert_called_once_with(mode='w', delete=False, suffix='_ssh_key')
# … earlier in test_ssh_identity_temp_file_creation_and_cleanup …
# Expect the temp file to be opened in binary mode now
mock_temp_file.assert_called_once_with(mode='wb', delete=False, suffix='_ssh_key')
# Ensure we write bytes, not str
mock_temp_file_instance.write.assert_called_once_with(TEST_SSH_KEY.encode('utf-8'))
# … following assertions (chmod, unlink, etc.) …
🤖 Prompt for AI Agents
In packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py around
line 574, the assertion currently expects mode='w' but the implementation should
open the temp file in binary mode; change the assertion to expect mode='wb' and
update any mock file-like object or return value used for the temp file so that
written SSH key data is provided/compared as bytes (i.e., encode the SSH key
string before asserting writes or side effects). Ensure the
mock_temp_file.assert_called_once_with uses mode='wb', delete=False,
suffix='_ssh_key' and adjust any subsequent mock write/read checks to use byte
strings.

@michalskrivanek
Copy link
Copy Markdown
Contributor

the keys are text, so no need to add "b"

@michalskrivanek
Copy link
Copy Markdown
Contributor

LGTM

@kirkbrauer kirkbrauer enabled auto-merge (squash) October 4, 2025 23:08
@kirkbrauer kirkbrauer merged commit 0f1555f into jumpstarter-dev:main Oct 4, 2025
18 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 21, 2025
mangelajo added a commit that referenced this pull request Nov 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants